package com.nidu.demo.dict.gatewayimpl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.cola.dto.PageQuery;
import com.alibaba.cola.dto.PageResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nidu.demo.dict.convertor.DictDataConvertor;
import com.nidu.demo.dict.gateway.DictDataGateway;
import com.nidu.demo.dict.mapper.DictDataMapper;
import com.nidu.demo.dict.mapper.dataobject.DictDataDO;
import com.nidu.demo.dict.model.DictData;
import com.nidu.demo.dict.model.DictDataCriteria;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Set;
import java.util.List;

@Component
@RequiredArgsConstructor
public class DictDataGatewayImpl implements DictDataGateway {

    private final DictDataMapper mapper;

    private final DictDataConvertor convertor;

    @Override
    @CacheEvict(cacheNames = "dictData", allEntries = true)
    public DictData create(DictData dictData) {
        DictDataDO dictDataDO = convertor.toDataObject(dictData);
        mapper.insert(dictDataDO);
        return convertor.toDomainObject(dictDataDO);
    }

    @Override
    @CacheEvict(cacheNames = "dictData", allEntries = true)
    public DictData update(DictData dictData) {
        DictDataDO dictDataDO = convertor.toDataObject(dictData);
        mapper.updateById(dictDataDO);
        return convertor.toDomainObject(dictDataDO);
    }

    @Override
    @Cacheable(cacheNames = "dictData", key = "'id:' + #id", unless = "#result == null")
    public DictData getById(Long id) {
        DictDataDO dictDataDO = mapper.selectById(id);
        if (dictDataDO == null) {
            return null;
        }
        return convertor.toDomainObject(dictDataDO);
    }

    @Override
    @Cacheable(cacheNames = "dictData", key = "'type_value:' + #dictType + ':' + #value", unless = "#result == null")
    public DictData getByTypeAndValue(String dictType, String value) {
        DictDataDO dictDataDO = mapper.selectByTypeAndValue(dictType, value);
        if (dictDataDO == null) {
            return null;
        }
        return convertor.toDomainObject(dictDataDO);
    }

    @Override
    @CacheEvict(cacheNames = "dictData", allEntries = true)
    public void deleteById(Long id) {
        mapper.deleteById(id);
    }

    @Override
    @CacheEvict(cacheNames = "dictData", allEntries = true)
    public void deleteByIds(Set<Long> ids) {
        mapper.deleteByIds(ids);
    }

    @Override
    public List<DictData> listByCondition(DictDataCriteria criteria) {
        LambdaQueryWrapper<DictDataDO> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(!StrUtil.isEmpty(criteria.getDictType()), DictDataDO::getDictType, criteria.getDictType());
        // 可以根据需要添加更多查询条件
        List<DictDataDO> dictDataDOS = mapper.selectList(wrapper);
        if (CollUtil.isEmpty(dictDataDOS)) {
            return new ArrayList<>();
        }
        return convertor.toDomainObjects(dictDataDOS);
    }

    @Override
    public PageResponse<DictData> pageByCondition(DictDataCriteria criteria) {
        // 创建查询条件
        LambdaQueryWrapper<DictDataDO> wrapper = new LambdaQueryWrapper<>();

        LocalDateTime[] createTime = criteria.getCreateTime();
        if (createTime != null) {
            if (createTime.length == 1 && createTime[0] != null) {
                wrapper.ge(DictDataDO::getCreateTime, createTime[0]);
            } else if (createTime.length > 1 && createTime[0] != null && createTime[1] != null) {
                wrapper.between(DictDataDO::getCreateTime, createTime[0], createTime[1]);
            }
        }

        wrapper.eq(!StrUtil.isEmpty(criteria.getDictType()), DictDataDO::getDictType, criteria.getDictType());

        // 创建分页对象，确保使用 DictDataDO
        Page<DictDataDO> page = new Page<>(criteria.getPageIndex(), criteria.getPageSize());

        // 排序字段
        if (!StrUtil.isEmpty(criteria.getOrderBy())) {
            if (PageQuery.DESC.equals(criteria.getOrderDirection())) {
                page.addOrder(OrderItem.desc(criteria.getOrderBy()));
            } else {
                page.addOrder(OrderItem.asc(criteria.getOrderBy()));
            }
        }
        mapper.selectPage(page, wrapper);
        List<DictData> companies = convertor.toDomainObjects(page.getRecords());
        return PageResponse.of(companies, (int) page.getTotal(), (int) page.getSize(), (int) page.getCurrent());
    }

}